package cn.bx.bid.ctrl;

import cn.bx.bid.entity.*;
import cn.bx.bid.service.ProjectService;


import cn.bx.bid.util.LogUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;


@Controller
public class ProjectController {
    @Value("${uploadPath}")
    private String uploadPath;

    @Resource
    ProjectService projectService;

/*  //项目增加跳转
    @RequestMapping("toProjectaddtiao")
    public String projectAddtiao(){
        return "projectadd";
    }*/

    @GetMapping("projectseach")
    @ResponseBody
    public Page<Project> search(@RequestParam(value = "page", defaultValue = "1") int pageNo, @RequestParam(value = "limit", defaultValue = "10") int limit, @RequestParam(value = "name", required = false) String name, @RequestParam(value = "category", required = false) String category) {

        Page<Project> p = projectService.paging(pageNo, limit, name, category);
        return p;
    }

    @RequestMapping("projectlook")
    @ResponseBody
    public AjaxResult get(@RequestParam(value = "id")Long id) {

        Project project= projectService.get(id);
        if(project!=null) {
            return AjaxResult.success("查询成功", project);
        }
        return  AjaxResult.error("查询失败");
    }

    //确定参加
    @RequestMapping("profRoleProject")
    @ResponseBody
    public String  profRoleProject(@RequestParam(value = "pfid") long pfid,@RequestParam(value = "projid") long projid)
          {
         int r=this.projectService.profRoleProject(pfid,projid);
              System.out.println("y>>>>>>>>>>>>>>>>>>>>"+r);

        String msg="{\"result\":"+(r>0)+"}";
              System.out.println("y>>>>>>>>>>>>>>>>>>>>"+msg);
   return  msg;

    }

    //不参加
    @RequestMapping("profnotPresentProject")
    @ResponseBody
    public String profnotPresentProject(@RequestParam(value = "pfid") long pfid,@RequestParam(value = "proid") long projectid,@RequestParam(value = "reason") String reason)
            throws ServletException, IOException {


        //待续
        int r=projectService.profnotPresentProject(pfid,projectid,reason);
        System.out.println("n>>>>>>>>>>>>>>>>>>>>"+r);
        String msg="{\"result\":"+(r>0)+"}";
        System.out.println("n>>>>>>>>>>>>>>>>>>>>"+msg);
        return  msg;

    }

    @RequestMapping("projectChoosingProfs")
    @ResponseBody
    public String  projectChoosingProfs(@RequestParam(value = "projid") long projid) {

     Page<ProfessorEnroll> p =projectService.searchProfessorInProjs(projid);
        String str = JSON.toJSONStringWithDateFormat(p, "yyyy-MM-dd hh时MM分", SerializerFeature.WriteMapNullValue,SerializerFeature.WriteNullStringAsEmpty);
        return str;
    }

    //抽取专家
     @RequestMapping("randomSelect")
     @ResponseBody
    public String  randomSelect(@RequestParam(value = "pjid") long pjid,@RequestParam(value = "category")String category,@RequestParam(value = "distance",required = false)Double distance) {

        Project p =projectService.get(pjid);
        //考虑了能来的，去掉确定不来的，不确定的也加上了
        int hasSelected =projectService.getPrentProfessors(pjid);
        String msg = "";
        try {
            if (p.getStatus() == 1) {
                msg = "{\"result\":false,\"msg\":\"此项目已经结束，不能再选\"}";
            } else if (hasSelected >= p.getProfessorNum()) {
                msg = "{\"result\":false,\"msg\":\"此项目人数已经满足，无需再选\"}";
            } else {
                List<Professor> list = projectService.getProfessorsForChoose(pjid, category);
                //
                if (distance != null) {//distance>0
                    //根据距离过滤URLEncoder.encode(p.getAddress(),"utf-8")
              //      Jw location = getPos(p.getAddress());//项目开标地址的经纬度
                    Jw location = getPos(URLEncoder.encode(p.getAddress(),"utf-8"));//项目开标地址的经纬度
                    System.out.println("开会地点。。。。。。" + location);
                    if (location != null) {
                        Iterator<Professor> r = list.iterator();
                        while (r.hasNext()) {
                            Professor t = r.next();
                      //      Jw l2 = getPos(t.getAddress());//获得专家的经纬度
                            Jw l2 = getPos(URLEncoder.encode(t.getAddress(),"utf-8"));//获得专家的经纬度
                            if (l2 == null)
                                continue;//地址不确定的先不考虑
                            System.out.println("专家：" + t.getProfessorName() + " 住址：" + l2 + ">>>距离：" + l2.dis(location) + "公里");
                            if (l2.dis(location) > distance) {
                                r.remove();//删除当前专家
                            }
                        }
                    }
                }
                if (list.size() < (p.getProfessorNum() - hasSelected)) {
                    msg = "{\"result\":false,\"msg\":\"没有找到满足人数的专家，缺少" + (Math.abs(list.size() - (p.getProfessorNum() - hasSelected))) + "人，先修改条件或者重新选择距离再试\"}";
                } else {
                    //开始随机选择
                    int need = p.getProfessorNum() - hasSelected;
                    long ids[] = new long[need];
                    int index = 0;
                    while (true) {
                        int r = (int) (Math.random() * list.size());
                        ids[index++] = list.get(r).getId();
                        list.remove(r);
                        if (index >= ids.length)
                            break;
                    }
                    //保存到数据库
                    int result =projectService.saveChooseResult(p, ids);
                    msg = "{\"result\":true,\"msg\":\"成功抽选" + need + "名专家！\"}";
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            msg = "{\"result\":false,\"msg\":\"网络不稳定，稍后再试！\"}";
        }
       return  msg;
    }

    //添加项目
    @PostMapping("projectAdd")
    @ResponseBody  //返回为Json注解
    public AjaxResult project(HttpSession s, HttpServletRequest request, @ModelAttribute("p") Project project, @RequestParam(name = "fujian", required = false) MultipartFile file) {
        LogUtil.info("file>>>>>>>>>>>  " + uploadPath);
        if (!(file == null || file.isEmpty())) {
            String oldName = file.getOriginalFilename();//文件名
            String prefix = oldName.substring(oldName.lastIndexOf("."));//截取后缀

            String newName = UUID.randomUUID() + prefix;
            LogUtil.info("newName>>>>>>>>>>>" + newName);
          //  File path = new File(s.getServletContext().getRealPath("doc"));
            File path =new File(uploadPath);
            LogUtil.info("文件的路径：" + path.getAbsolutePath());
            if (path.exists() == false) {
                path.mkdir();
            }
            try {
                file.transferTo(new File(path, newName));
                project.setProjectFilePath(newName);
            } catch (IOException e) {
                e.printStackTrace();
            }


        }
        int a = projectService.projectadd(project);
        if (a > 0) {
            return AjaxResult.success("增加成功");
        }
        return AjaxResult.error("增加失败");
    }

    //考虑把key放入外部文件中，好灵活配置
    public static final String url = "http://api.map.baidu.com/geocoder/v2/?address=%s&output=json&ak=B4bd9e22c0a580cd04b0e84b17bf9eb6";

    // 获得经纬度
    private Jw getPos(String addr) {
        String str = getDistance(String.format(url, addr));
        Map m = (Map) JSON.parse(str);

        if (!new Integer(0).equals(m.get("status"))) {
            return null;
        }
        Map m2 = (Map) ((Map) m.get("result")).get("location");
        System.out.println(m2);
        double lng = Double.parseDouble(m2.get("lng").toString());
        double lat = Double.parseDouble(m2.get("lat").toString());
        return new Jw(lat, lng);
    }

    //
    public String getDistance(String url) {
        // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 创建Get请求
        HttpGet httpGet = new HttpGet(url);

        // 响应模型
        CloseableHttpResponse response = null;
        try {
            // 由客户端执行(发送)Get请求
            response = httpClient.execute(httpGet);
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();
            System.out.println("响应状态为:" + response.getStatusLine());
            if (responseEntity != null) {
                System.out.println("响应内容长度为:" + responseEntity.getContentLength());
                // System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
                return EntityUtils.toString(responseEntity);
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                // 释放资源
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }


    @InitBinder
    public void initBinder(WebDataBinder binder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
        // true:允许输入空值，false:不能为空值
    }

}
    //经纬度描述类
    class Jw {
        public double lat, lng;

        public Jw() {
        }

        public Jw(double lat, double lng) {
            super();
            this.lat = lat;
            this.lng = lng;
        }

        public double dis(Jw w) {
            return getDistance(this.lat, this.lng, w.lat, w.lng);
        }

        @Override
        public String toString() {
            return "Jw [lat=" + lat + ", lng=" + lng + "]";
        }

        public static double getDistance(double Lat_A, double Lng_A, double Lat_B, double Lng_B) {
            double ra = 6378.140;
            double rb = 6356.755;
            double flatten = (ra - rb) / ra;
            double rad_lat_A = Math.toRadians(Lat_A);
            double rad_lng_A = Math.toRadians(Lng_A);
            double rad_lat_B = Math.toRadians(Lat_B);
            double rad_lng_B = Math.toRadians(Lng_B);
            double pA = Math.atan(rb / ra * Math.tan(rad_lat_A));
            double pB = Math.atan(rb / ra * Math.tan(rad_lat_B));
            double xx = Math
                    .acos(Math.sin(pA) * Math.sin(pB) + Math.cos(pA) * Math.cos(pB) * Math.cos(rad_lng_A - rad_lng_B));
            double c1 = (Math.sin((xx) - xx) * (Math.sin(pA) + Math.sin(pB)) * 2 / Math.cos(xx / 2) * 2);
            double c2 = (Math.sin(xx) + xx) * (Math.sin(pA) - Math.sin(pB)) * 2 / Math.sin(xx / 2) * 2;
            double dr = flatten / 8 * (c1 - c2);
            double distance = ra * (xx + dr);
            // DecimalFormat format = new DecimalFormat("###.000");
            // distance = Double.parseDouble(format.format(distance));
            return Math.abs(distance);
        }
    }